'''
Author: duliang thinktanker@163.com
Date: 2024-03-02 16:13:14
LastEditors: duliang thinktanker@163.com
LastEditTime: 2024-04-14 23:11:41
FilePath: \opencv2\cutimage.py
Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
'''
import cv2
import numpy as np
import tkinter as tk
from tkinter.simpledialog import askstring
from tkinter.messagebox import showinfo, askyesno
from tkinter import filedialog
import re
# img_path = './2z.png'
img_path = './test1.png'


def open_file():
    """
    弹出文件选择对话框，并获取所选文件的路径。
    """
    # 打开文件对话框
    file_path = filedialog.askopenfilename(
        title="Open File",
        # 设置初始目录（可选）
        initialdir="/path/to/default/directory",
        # 指定允许选择的文件类型（可选）
        filetypes=(("JPG Files", "*.jpg"), ("PNG Files", "*.png"),
                   ("All Files", "*.*")),
    )

    # 如果用户没有取消选择（即选择了文件），则打印文件路径
    if file_path:
        print(f"Selected file: {file_path}")
        # 这里可以进一步处理文件，如打开、读取或加载到程序中
        return file_path


def draw_rectangle(event, x, y, flags, param):
    global rect_start, is_drawing, rect, img

    if event == cv2.EVENT_LBUTTONDOWN:
        rect_start = (x, y)  # 记录矩形开始点
        is_drawing = True

    elif event == cv2.EVENT_MOUSEMOVE and is_drawing:
        rect_end = (x, y)
        img = cv2.imread(img_path)
        cv2.rectangle(img, rect_start, rect_end, (0, 255, 0), 2)
        cv2.imshow('Image', img)  # 实时更新显示窗口

    elif event == cv2.EVENT_LBUTTONUP:
        rect_end = (x, y)
        # img = cv2.imread('./2z.png')
        cv2.rectangle(img, rect_start, rect_end, (0, 255, 0), 2)
        rect.append([
            min(rect_start[0], rect_end[0]),
            min(rect_start[1], rect_end[1]),
            max(rect_start[0], rect_end[0]),
            max(rect_start[1], rect_end[1])
        ])
        is_drawing = False
    elif event == cv2.EVENT_RBUTTONDOWN:
        rect_start = None
        is_drawing = False
        rect.clear()
        img = cv2.imread(img_path)
        cv2.imshow('Image', img)


def get_user_input():
    user_input = askstring("输入框", "输入文件名")
    if user_input:
        # print(f"文件名：{user_input}")
        return user_input


def draw_rectangle_from_recttxt(result_path, image_path):
    rect_list = []
    img = cv2.imread(image_path)
    height, width, channels = img.shape
    width = width // 40  #48
    height = height // 40  #27
    with open(result_path, 'r', encoding='utf-8') as f:
        result = f.read()
        nums = re.findall(r'\d+\.\d+', result)
        nums = list(map(float, nums))
        # print(nums)
        for i in range(0, len(nums), 4):
            rect_list.append([
                width * int(nums[i]), height * int(nums[i + 1]),
                width * int(nums[i + 2]), height * int(nums[i + 3])
            ])
    if rect_list:
        for rect in rect_list:
            cv2.rectangle(img, (rect[0], rect[1]), (rect[2], rect[3]),
                          (0, 255, 0), 2)
        while True:
            cv2.imshow('Image', img)
            key = cv2.waitKey(1) & 0xFF
            if key == ord('q'):
                break
        cv2.destroyAllWindows()


if __name__ == '__main__':
    # draw_rectangle_from_recttxt('./result.txt', './test1.png')
    # exit(0)
    root = tk.Tk()
    root.withdraw()  # 隐藏主窗口
    img_path = open_file()
    if not img_path:
        exit(0)
    # 加载或初始化一张图片
    img = cv2.imread(img_path)  # 替换为你要处理的图片路径
    height, width, _ = img.shape
    min_height = height // 40
    min_width = width // 40
    if img is None:
        img = np.zeros((500, 500, 3), np.uint8)  # 或者使用空白图像作为默认

    # 初始化矩形框起始点和是否正在绘制标志
    rect_start = None
    is_drawing = False
    rect = []

    # 创建一个窗口并设置鼠标回调函数
    cv2.namedWindow('Image')
    cv2.setMouseCallback('Image', draw_rectangle)
    showinfo("提示", "按住鼠标左键框选范围\n按 'r' 或鼠标右键 清空\n按 's' 保存\n按 'q' 退出")
    pic_namelist = []
    results = []
    while True:
        cv2.imshow('Image', img)
        # 检查按键事件
        key = cv2.waitKey(1) & 0xFF
        # 保存
        if rect and (key == ord('s') or key == ord(' ')):
            rect_list = rect[-1]
            input_str = get_user_input()
            left_ratio = round(rect_list[0] / min_width, 1)
            top_ratio = round(rect_list[1] / min_height, 1)
            right_ratio = round(rect_list[2] / min_width, 1)
            bottom_ratio = round(rect_list[3] / min_height, 1)
            result = f"{input_str} {left_ratio, top_ratio, right_ratio, bottom_ratio}"
            print(result)
            response = askyesno("是否保存", result)
            if response:
                print("用户选择了保存")
                pic_namelist.append(input_str)
                results.append(
                    f'''#{input_str}\nleft = width * {left_ratio}\ntop = height * {top_ratio}\nright = width * {right_ratio}\nbottom = height * {bottom_ratio}\nbox1 = (int(left), int(top), int(right), int(bottom))\nbox_list.append(box1)'''
                )
                with open('./result.txt', 'a', encoding='utf-8') as f:
                    f.write(results[-1] + '\n')
                with open('./rect.txt', 'a', encoding='utf-8') as f:
                    f.write(f'{rect_list}\n')
            else:
                print("用户取消了保存")
            continue
        # 当用户按下 'r' 键时清空已画的矩形并重新开始
        if key == ord('r'):
            img = cv2.imread(img_path)  # 重新加载原图（可选）
            rect.clear()
            cv2.imshow('Image', img)
        # 按 'q' 键退出
        elif key == ord('q'):
            break
    cv2.destroyAllWindows()
